﻿using System;
using System.Collections.Generic;

namespace Battle.Engine.LogicModel
{
    //一个FCast可以分成 1个或2个FRelease,,FRelease表示伤害事件或者射击事件
    public class FRelease
    {
        public FSkillCast cast;     //本次
        public bool isCast;         //是伤害点还是射击点
        public double oritime;      //生效时间
        public double time;         //内部数据,用来保存触发时间点
        public bool isLast;         //是否是最后一次

        //@isCast 是伤害点还是射击点
        public void init(FSkillCast cast, bool isCast, double time)
        {
            this.cast = cast;
            this.isCast = isCast;
            this.oritime = time;
            this.time = 0;
            this.isLast = false;
        }

        public void Do(EngineData data)
        {
            if (this.cast.skill.actor.state == FActorState.DEAD)
                return;

            //技能输出
            FExportOnceData exportOnceData = new FExportOnceData();
            exportOnceData.Init(this.cast);

            FSkill skill = this.cast.skill;
            FActor actor = this.cast.skill.actor;
            actor.curSkillClass = skill.skillClass;

            if(skill.target == null)
            {
                Debug.LogFightMsg("--------do release: time=" + data.roundTime + ", skillid:" + this.cast.skill.id + ", castid:" + this.cast.id + ", skill.target == null");
                return;
            }
            Debug.LogFightMsg("--------do release: time=" + data.roundTime + ", skillid:" + this.cast.skill.id + ", castid:" + this.cast.id + ", iscast=" + this.isCast);
#if UNITY_EDITOR && TEST
            if (skill.id.Equals("009_2") == true && this.cast.id.Equals("188") == true)
            {
                int aa = 0;
                aa = 1;
            }
#endif
            if (this.isCast)
            {
                if (this.cast.id.Equals(skill.casts[0].id))
                {//第一次cast直接取castTargets
                    skill.isFirstCastStart = true;
                    if (skill.IsUltimate)
                    {//大招消耗怒气
                        FExportOnceData exportUltimateCostAnger = new FExportOnceData();
                        actor.player.AddAnger(-actor.ultimateCostAnger, actor, exportUltimateCostAnger);
                        //前端直接扣除，不进行传递
                        //data.exports.Add(exportUltimateCostAnger);
                    }
                    //技能释放后需要更新当前技能冷却时间
                    skill.cooldownCur += skill.cooldown;  //由于期间可能有buff减免冷却回合数，因此在此做加法而非直接赋值处理
                }
                else if ((SelectStrategy)cast.selectStrategy != SelectStrategy.SAME_AS_LAST_RELEASE)
                {//如果与上一次release的目标不一样，则更新目标列表
                    List<SelectLimitCondition> limitConditions = data.LimitConditions(true, false, true);
                    //更新目标
                    skill.castTargets.Clear();
                    skill.castTargets.AddRange(data.SelectTargetActors(true, cast.selectStrategy, actor, skill.target, limitConditions));
                }
                
                //加载攻击时的buff(包括非技能限定buff)
                actor.buffProc.LoadAttBuff(this.cast, exportOnceData);

                if (cast.exportFactor == 0)
                {
                    foreach (var target in skill.castTargets)
                    {
                        FExportValue exportValue = new FExportValue();
                        exportValue.Init(exportOnceData.source, target, ExportValueClass.HP, 0, 0, HpInfSpecialType.None);
                        exportOnceData.values.Add(exportValue);
                    }
                    data.exports.Insert(0, exportOnceData);//cast 要放第一个，其他的暂时按顺序走
                    if (data.callback != null)
                        data.callback.SkillCast(this);
                    return;
                }

                FPlayer enemyPlayer = data.getPlayerByCampType(actor.player.enemyCamp);
                foreach (var target in skill.castTargets)
                {
                    target.buffProc.LoadHurtBuffByTimer(this.cast, TalentBuffTriggerTimer.BeCastNotHit, exportOnceData);
                    // 命中率
                    // Damage : 1 - (1 - (我方命中 - 敌方闪避)) * 状态闪避系数 = 命中率
                    // Health : 1
                    // 大招必中
                    // 100%命中BUFF必中
                    double hitRadio = 0;
                    if (this.cast.exportType == AttackType.TREAT
                        || skill.IsUltimate || actor.stateManager.IsMustHit)
                    {
                        hitRadio = 1;
                    }
                    else
                    {
                        //自己的命中率
                        var ownerHit = actor.attribute.hit;
                        //目标的闪避率
                        var targetDodge = target.attribute.dodge;
                        double speDodgeFactor = 1;//闪避因子：浮天倒地状态下闪避减半
                        if ((target.speState == SpeState.FLOAT && target.defaultSpeState != SpeState.FLOAT) ||
                            (target.speState == SpeState.FALL && target.defaultSpeState != SpeState.FALL))
                        {
                            speDodgeFactor = target.attribute.floatBreakHitFactor;
                        }
                        hitRadio = 1 - (1 - (ownerHit - targetDodge)) * speDodgeFactor;

                    }

                    if (data.random.value > hitRadio)
                    {// 算概率，MISS了
                        Debug.LogFightMsg("--------MISS heroId:" + target.heroId);
                        FExportValue exportValue = new FExportValue();
                        exportValue.Init(exportOnceData.source, target, ExportValueClass.HP, 0, 0, HpInfSpecialType.Miss);
                        exportOnceData.values.Add(exportValue);
                        //处理闪避时的天赋buff
                        target.buffProc.LoadHurtBuffByTimer(this.cast, TalentBuffTriggerTimer.Dodge, exportOnceData);

                        //清除被选中过程中当时生效的buff
                        actor.buffManager.ClearOnceHitBuff();
                        target.buffManager.ClearOnceHitBuff();
                        continue;
                    }
                    //命中
                    actor.behitActors.Add(target);
                    //加载命中时的buff（包括技能限定buff）
                    actor.buffProc.LoadHitBuff(this.cast, target, exportOnceData);
                    target.buffProc.LoadBeHitBuff(this.cast, exportOnceData);
                    //是否buff无效
                    bool isUneffectBuffsOnce = false;
                    //判定是否暴击
                    bool isCri = false;
                    double criFactor = 1;
                    if (this.cast.exportType == AttackType.TREAT)
                    {
                        //暴击计算
                        if (actor.stateManager.IsMustCri || data.random.value <= actor.attribute.cri)
                        {
                            criFactor += actor.attribute.criFactor;
                            isCri = true;
                        }
                        //治疗技能 加血=((攻击力*技能百分比)*(1+治疗加成)+(治疗值加成+被治疗值加成))*(1+Ramdom(-0.1,0.1))*暴击系数
                        var healValue = (actor.attribute.att.value * cast.exportFactor) * (1 + actor.attribute.treatAdd);
                        var healAdd = actor.attribute.cure + target.attribute.heal;
                        var totalHeal = (healValue + healAdd) * (1 + data.random.Range(-0.1, 0.1))* criFactor;
                        if (target.stateManager.IsForbidAddHp)
                        {//目标禁止回血
                            Debug.LogFightMsg("--------ForbidAddHp heroId:" + target.heroId);
                            FExportValue exportValue = new FExportValue();
                            exportValue.Init(exportOnceData.source, target, ExportValueClass.HP, 0, 0, HpInfSpecialType.Immune);
                            exportOnceData.values.Add(exportValue);
                        }
                        else
                        {
                            HpInfSpecialType type;
                            if (isCri)
                            {
                                type = HpInfSpecialType.Crit;
                            }
                            else
                            {
                                type = HpInfSpecialType.None;
                            }
                            target.AddHp(totalHeal, exportOnceData, type, this.cast.exportType);
                        }

                        if (!actor.stateManager.IsForbidAddSkillAnger)
                        {//处理怒气加成
                            var addSourceAnger = this.cast.addAnger * (1+ actor.attribute.peranger);
                            actor.player.AddAnger(addSourceAnger, actor, exportOnceData);
                        }

                    }
                    else if (this.cast.exportType == AttackType.PHY || this.cast.exportType == AttackType.MAG)
                    {
                        if (target.stateManager.IsInvincible)
                        {//处理无敌,不受浮空倒地
                            Debug.LogFightMsg("--------Invincible heroId:" + target.heroId);
                            FExportValue exportValue = new FExportValue();
                            exportValue.Init(exportOnceData.source, target, ExportValueClass.HP, 0, 0, HpInfSpecialType.Invincible);
                            exportOnceData.values.Add(exportValue);
                        }
                        else
                        {
                            if (target.stateManager.IsUneffectBuffOnce)
                            {
                                target.buffManager.uneffectBuffsOnce();
                                isUneffectBuffsOnce = true;
                            }
                            //暴击计算
                            double criRadio = actor.attribute.cri- target.attribute.antiCri;
                            if (actor.stateManager.IsMustCri || data.random.value <= criRadio)
                            {
                                //处理暴击时的天赋buff
                                actor.buffProc.LoadCriBuff(this.cast, target, exportOnceData);
                                target.buffProc.LoadHurtBuffByTimer(this.cast, TalentBuffTriggerTimer.BeCri, exportOnceData);
                                criFactor += actor.attribute.criFactor;
                                isCri = true;
                            }

                            //处理浮天倒地
                            ProcSPEState(this.cast, target, ref exportOnceData);
                            if (actor.player.isPlayer && target.speState == SpeState.FALL)
                            {
                                //Debug.LogFightMsg("target.speState == SpeState.FALL:" + target.uniqueId);
                                ProcMagicStone(target, data, actor.player, ref exportOnceData);
                            }
                            else if (actor.player.isPlayer && target.speState == SpeState.FLOAT)
                            {
                                //Debug.LogFightMsg("target.speState == SpeState.FLOAT:" + target.uniqueId);
                                if (data.random.Range(0f,1f) <= 0.15f )
                                {
                                    actor.player.waterBallNum++;
                                    Debug.LogFightMsg("--------ProcWaterBall:stoneActor from " + target.heroId);
                                    //输出
                                    FExportValue exportValue = new FExportValue();
                                    exportValue.Init(target, exportOnceData.source, ExportValueClass.WATER_BALL, 1);
                                    exportOnceData.values.Add(exportValue);
                                }
                            }
                            //攻击技能 减血=(攻击+物法攻击-目标物法防御)*技能百分比*(1+伤害加成-目标伤害减免-目标物法伤害减免)*(1+Ramdom(-0.1,0.1))*暴击系数
                            double att = actor.attribute.att.value;
                            double attAdd = this.cast.exportType == AttackType.PHY ? actor.attribute.patt.value : actor.attribute.matt.value;
                            double def = this.cast.exportType == AttackType.PHY ? target.attribute.pdef.value : target.attribute.mdef.value;
                            double damageAdd = actor.attribute.damageAdd + actor.player.GetComboHitDamageFactor();
                            double damageReduce = target.attribute.damageReduce;
                            double damageReduceAdd = this.cast.exportType == AttackType.PHY ? target.attribute.pdamageReduce : target.attribute.mdamageReduce;
                            if (actor.stateManager.IsImmuneDef)
                            {//无视对方防御及免伤
                                def = 0;
                                damageReduce = 0;
                                damageReduceAdd = 0;
                            }
                            double damage = (1 + damageAdd - damageReduce - damageReduceAdd) < 0 ? 0 : (1 + damageAdd - damageReduce - damageReduceAdd);
                            double totalDamage = 0;
                            //判断是否有承担伤害的队友
                            if (target.attribute.damShareActors.Count > 0)
                            {
                                double sdamfactor = cast.exportFactor * target.attribute.damShareFactor / target.attribute.damShareActors.Count;
                                foreach (var sactor in target.attribute.damShareActors)
                                {
                                    double sdef = this.cast.exportType == AttackType.PHY ? sactor.attribute.pdef.value : sactor.attribute.mdef.value;
                                    double sdamageReduce = sactor.attribute.damageReduce;
                                    double sdamageReduceAdd = this.cast.exportType == AttackType.PHY ? sactor.attribute.pdamageReduce : sactor.attribute.mdamageReduce;
                                    double sdamage = (1 + damageAdd - sdamageReduce - sdamageReduceAdd) < 0 ? 0 : (1 + damageAdd - sdamageReduce - sdamageReduceAdd);
                                    double stotalDamage = (att + attAdd - sdef) * sdamfactor * sdamage * (1 + data.random.Range(-0.1, 0.1));
                                    double sreducedamFactor = 0;
                                    if (!actor.stateManager.IsMustHit && sactor.attribute.dodge > actor.attribute.hit)
                                    {
                                        sreducedamFactor = sactor.attribute.dodge - actor.attribute.hit;
                                        if(sreducedamFactor > 0.5)
                                        {
                                            sreducedamFactor = 0.5;
                                        }
                                        sreducedamFactor = data.random.Range(0, sreducedamFactor * 2);
                                    }
                                    stotalDamage = stotalDamage * (1 - sreducedamFactor);
                                    if (stotalDamage < 1)
                                    {
                                        stotalDamage = 1;
                                    }
                                    sactor.AddHp(-stotalDamage, exportOnceData, HpInfSpecialType.AdditionAtt, this.cast.exportType);
                                }
                                totalDamage = (att + attAdd - def) * cast.exportFactor * (1 - target.attribute.damShareFactor) * damage * (1 + data.random.Range(-0.1, 0.1)) * criFactor;

                                double reducedamFactor = 0;
                                if (!actor.stateManager.IsMustHit && target.attribute.dodge > actor.attribute.hit)
                                {
                                    reducedamFactor = target.attribute.dodge - actor.attribute.hit;
                                    if (reducedamFactor > 0.5)
                                    {
                                        reducedamFactor = 0.5;
                                    }
                                    reducedamFactor = data.random.Range(0, reducedamFactor * 2);
                                }
                                totalDamage = totalDamage * (1 - reducedamFactor);
                            }
                            else
                            {
                                totalDamage = (att + attAdd - def) * cast.exportFactor * damage * (1 + data.random.Range(-0.1, 0.1)) * criFactor;

                                double reducedamFactor = 0;
                                if (!actor.stateManager.IsMustHit && target.attribute.dodge > actor.attribute.hit)
                                {
                                    reducedamFactor = target.attribute.dodge - actor.attribute.hit;
                                    if (reducedamFactor > 0.5)
                                    {
                                        reducedamFactor = 0.5;
                                    }
                                    reducedamFactor = data.random.Range(0, reducedamFactor * 2);
                                }
                                totalDamage = totalDamage * (1 - reducedamFactor);
                            }
                            //处理浮空倒地造成的血量加成
                            double hpFactor;
                            hpFactor = data.tableDataUtil.GetSpecialStateHpFactor(this.cast.advSpeState, target.speState);
                            totalDamage = totalDamage * hpFactor;
                            bool isBlock = false;
                            if(data.random.value <= target.attribute.block)
                            {
                                totalDamage = totalDamage * (1 + target.attribute.blockDam);
                                isBlock = true;
                                //处理格挡时的天赋buff
                                target.buffProc.LoadHurtBuffByTimer(this.cast, TalentBuffTriggerTimer.Block, exportOnceData);
                            }
                            HpInfSpecialType type;
                            if (isCri && isBlock)
                            {
                                type = HpInfSpecialType.CritAndBlock;
                            }
                            else if (isCri)
                            {
                                type = HpInfSpecialType.Crit;
                            }
                            else if (isBlock)
                            {
                                type = HpInfSpecialType.Block;
                            }
                            else
                            {
                                type = HpInfSpecialType.None;
                            }
                            if(actor.stateManager.IsCanNotKill && totalDamage > (target.attribute.hp - 1))
                            {//无法击杀，给目标留最后一滴血
                                double shield = this.cast.exportType == AttackType.PHY ? target.attribute.pshield : target.attribute.mshield;
                                totalDamage = target.attribute.hp + shield - 1;
                            }
                            if (totalDamage < 1)
                            {
                                totalDamage = 1;
                            }
                            target.AddHp(-totalDamage, exportOnceData, type, this.cast.exportType);
                            //有目标需要承受同等伤害
                            if (actor.attribute.sameDamForRandom > 0)
                            {
                                if(skill.sameDamTargets.Count <= 0)
                                {
                                    List<FActor> acts = new List<FActor>();
                                    foreach(FActor act in enemyPlayer.actors)
                                    {
                                        if(act.state != FActorState.DEAD && act.state != FActorState.WAEKDEAD && act.uniqueId.Equals(target.uniqueId) == false)
                                        {
                                            acts.Add(act);
                                        }
                                    }
                                    if(acts.Count <= 0)
                                    {
                                        skill.sameDamTargets.Add(target);
                                    }
                                    else
                                    {//除目标以外其他随机一人
                                        skill.sameDamTargets.Add(acts[data.random.Range(0, acts.Count)]);
                                    }
                                }
                                foreach(FActor samea in skill.sameDamTargets)
                                {
                                    if(samea.state != FActorState.DEAD)
                                    {
                                        samea.AddHp(-(totalDamage * actor.attribute.sameDamForRandom), exportOnceData, HpInfSpecialType.AdditionAtt, this.cast.exportType);
                                    }
                                }
                            }
                            if (!skill.IsUltimate)
                            {//非大招才处理反伤
                                if (target.attribute.counterStrikeDam > 0 && target.state != FActorState.DEAD && target.state != FActorState.WAEKDEAD)
                                {
                                    //获取目标
                                    List<SelectLimitCondition> limitConditions = data.LimitConditions(true, true, true);
                                    List<FActor> counterStrikeTargets = data.SelectTargetActors(false, target.attribute.counterStrikeSelect, target, actor, limitConditions);
                                    foreach (var counterStrikeTarget in counterStrikeTargets)
                                    {
                                        double csatt = target.attribute.att.value;
                                        double csattAdd = target.attackType == AttackType.PHY ? target.attribute.patt.value : target.attribute.matt.value;
                                        double csdef = target.attackType == AttackType.PHY ? counterStrikeTarget.attribute.pdef.value : counterStrikeTarget.attribute.mdef.value;
                                        double csdamageAdd = target.attribute.damageAdd;
                                        double csdamageReduce = actor.attribute.damageReduce;
                                        double csdamageReduceAdd = target.attackType == AttackType.PHY ? counterStrikeTarget.attribute.pdamageReduce : counterStrikeTarget.attribute.mdamageReduce;
                                        if (target.attribute.counterStrikeReal)
                                        {//无视对方防御及免伤
                                            csdef = 0;
                                            csdamageReduce = 0;
                                            csdamageReduceAdd = 0;
                                        }
                                        double csdamage = (1 + csdamageAdd - csdamageReduce - csdamageReduceAdd) < 0 ? 0 : (1 + csdamageAdd - csdamageReduce - csdamageReduceAdd);
                                        double cstotalDamage = (csatt + csattAdd - csdef) * target.attribute.counterStrikeDam * csdamage;
                                        cstotalDamage = cstotalDamage < (totalDamage * target.attribute.counterStrikeDam) ? cstotalDamage : totalDamage * target.attribute.counterStrikeDam;
                                        if (cstotalDamage < 1)
                                        {
                                            cstotalDamage = 1;
                                        }
                                        counterStrikeTarget.AddHp(-cstotalDamage, exportOnceData, HpInfSpecialType.CounterStrike, target.attackType);
                                    }
                                }
                            }

                            //普通技能如果处在流血状态需要减流血伤害
                            if (!skill.IsUltimate && target.attribute.bleeding > 0)
                            {
                                double batt = actor.attribute.att.value;
                                double battAdd = actor.attribute.patt.value;
                                double bdef = target.attribute.pdef.value;
                                double bdamageAdd = actor.attribute.damageAdd;
                                double bdamageReduce = target.attribute.damageReduce;
                                double bdamageReduceAdd = target.attribute.pdamageReduce;
                                double bdamage = (1 + bdamageAdd - bdamageReduce - bdamageReduceAdd) < 0 ? 0 : (1 + bdamageAdd - bdamageReduce - bdamageReduceAdd);
                                double btotalDamage = (batt + battAdd - bdef) * target.attribute.bleeding * bdamage;

                                if (btotalDamage < 1)
                                {
                                    btotalDamage = 1;
                                }
                                target.AddHp(-btotalDamage, exportOnceData, HpInfSpecialType.Bleeding, AttackType.PHY);
                            }
                            if (actor.attribute.lifestealHp > 0)
                            {
                                List<FActor> ts = new List<FActor>();
                                List<SelectLimitCondition> limitConditions = data.LimitConditions(false, true, true);
                                ts = data.SelectTargetActors(false, actor.attribute.lifestealSelect, actor, skill.target, limitConditions);
                                foreach (var t in ts)
                                {
                                    if (!t.stateManager.IsForbidAddHp)
                                    {
                                        //吸血=伤害总量*吸血系数*(1+攻击者治疗加成百分比)+攻击者附加治疗值+吸血者附加被治疗值
                                        double lifestealHp = totalDamage * actor.attribute.lifestealHp * (1 + actor.attribute.treatAdd) + actor.attribute.cure + t.attribute.heal;
                                        t.AddHp(lifestealHp, exportOnceData, HpInfSpecialType.Lifesteal, AttackType.PHY);
                                    }
                                }
                            }
                        }
                        if (!actor.stateManager.IsForbidAddSkillAnger)
                        {
                            //处理浮空倒地造成的怒气加成
                            double apFactor;
                            apFactor = data.tableDataUtil.GetSpecialStateApFactor(this.cast.advSpeState, target.speState);
                            var addSourceAnger = this.cast.addAnger * (actor.attribute.peranger + apFactor);
                            actor.player.AddAnger(addSourceAnger, actor, exportOnceData);
                        }
                        //增加本次cast增加怒气的基础值到被击方
                        var addTargetAnger = this.cast.addAnger * (target.attribute.peranger + target.attribute.beHitAddAngerPercent);
                        target.player.AddAnger(addTargetAnger, target, exportOnceData);

                        if (isUneffectBuffsOnce)
                        {
                            target.buffManager.reeffectBuffsOnce();
                            isUneffectBuffsOnce = false;
                        }
                        //被击次数生效的buff更新
                        actor.buffManager.ProcDefEnd();
                    }
                    else
                    {
                        Debug.LogError("Wrong Data. SkillCast: " + this.cast.id + " SkillType: " + this.cast.exportType);
                    }
                    //清除命中过程中当时生效的buff
                    actor.buffManager.ClearOnceHitBuff();
                    target.buffManager.ClearOnceHitBuff();
                    //加连击数处理
                    actor.selfComboNum++;
                    actor.player.AddComboNum(1);
                    //优势攻击不为0，且处于对位攻击，连击数翻倍
                    if (this.cast.advSpeState != SpeState.NONE && this.cast.advSpeState == target.speState)
                    {
                        actor.selfComboNum++;
                        actor.player.AddComboNum(1);
                    }
                }
                //攻击次数生效的buff更新
                actor.buffManager.ProcAttEnd();
                foreach (var selfActor in actor.player.actors)
                {
                    //当时生效的buff清除
                    selfActor.buffManager.ClearOnceCastBuff();
                }
                foreach (var enemyActor in enemyPlayer.actors)
                {
                    //当时生效的buff清除
                    enemyActor.buffManager.ClearOnceCastBuff();
                }
                if (actor.state == FActorState.WAEKDEAD)
                {
                    actor.DoDead(data, exportOnceData);
                }
                //技能的最后一次release，判断当前技能打死了多少人
                if (this.isLast || actor.state == FActorState.DEAD)
                {
                    skill.sameDamTargets.Clear();//技能结束需要清除同等伤害者
                    //处理假死进入真死的状态
                    foreach (var enemyActor in enemyPlayer.actors)
                    {
                        if (enemyActor.state == FActorState.WAEKDEAD)
                        {
                            //如果当前没有别的敌人的技能目标是这个人,进入真死
                            if (data.GetNumActorAttack(enemyActor) == 0 || (data.GetNumActorAttack(enemyActor) == 1 && enemyActor.uniqueId.Equals(skill.target.uniqueId)))
                            {
                                enemyActor.DoDead(data, exportOnceData);
                                if(enemyActor.state == FActorState.DEAD)
                                {
                                    actor.buffProc.LoadKillBuff(skill);
                                }
                            }
                        }
                    }

                    if (skill.target.state != FActorState.DEAD)
                    {//技能目标没有死亡
                        actor.buffProc.LoadBuffByTimer(TalentBuffTriggerTimer.TargetNotDie);
                    }
                }
                //输出
                FExportValue exportComboValue = new FExportValue();
                exportComboValue.Init(exportOnceData.source, actor, ExportValueClass.DOUBLE_HIT, actor.player.comboNum);
                exportOnceData.values.Add(exportComboValue);

                //处理技能攻击后的buff
                actor.buffProc.LoadAttEndBuff(this.cast, exportOnceData);
                //过滤攻击后的buff是否有导致当前目标死亡（假死）
                if (this.isLast && skill.target.state == FActorState.WAEKDEAD)
                {
                    //目标只有自己正在攻击
                    if (data.GetNumActorAttack(skill.target) == 1)
                    {
                        skill.target.DoDead(data, exportOnceData);
                    }
                }

                data.exports.Insert(0,exportOnceData);//cast 要放第一个，其他的暂时按顺序走

                if (data.callback != null)
                    data.callback.SkillCast(this);
            }
            else
            {
                //通知
                if (data.callback != null)
                    data.callback.SkillProject(this);
            }
        }



        private void ProcSPEState(FSkillCast cast, FActor target, ref FExportOnceData exportOnceData) {
            FExportValue exportSPEValue = new FExportValue();
            double floatTime = target.getFloatTimeBySkill(this.cast.causeSpeState);
            double fallTime = target.getFallTimeBySkill(this.cast.causeSpeState);
            if (floatTime > 0)
            {
                exportSPEValue.Init(exportOnceData.source, target, ExportValueClass.SPE_STATE, (double)SpeState.FLOAT, floatTime);
            }
            else if (fallTime > 0)
            {
                exportSPEValue.Init(exportOnceData.source, target, ExportValueClass.SPE_STATE, (double)SpeState.FALL, fallTime);
            }
            else
            {
                exportSPEValue.Init(exportOnceData.source, target, ExportValueClass.SPE_STATE, (double)SpeState.NORMAL);
            }
            exportOnceData.values.Add(exportSPEValue);
        }

        private void ProcMagicStone(FActor target, EngineData data, FPlayer player, ref FExportOnceData exportOnceData)
        {
            //处理倒地时炎魔石的掉落
            double stoneChance = data.tableDataUtil.GetMagicStonePercent();
            if (data.random.value <= stoneChance)
            {//炎魔石掉落,获取炎魔石吸收的目标
                player.magicStoneNum++;
                //先取非死亡且炎魔石获得最少的人
                List<FActor> minStoneNumActors = new List<FActor>();
                foreach (var a in player.actors)
                {
                    if (a.state == FActorState.DEAD)
                    {
                        continue;
                    }
                    if (minStoneNumActors.Count == 0)
                    {
                        minStoneNumActors.Add(a);
                        continue;
                    }
                    if (a.attribute.magicStoneNum == minStoneNumActors[0].attribute.magicStoneNum)
                    {
                        minStoneNumActors.Add(a);
                    }
                    else if (a.attribute.magicStoneNum < minStoneNumActors[0].attribute.magicStoneNum)
                    {
                        minStoneNumActors.Clear();
                        minStoneNumActors.Add(a);
                    }
                }
                //优先获取大招未在CD状态的actor
                List<FActor> USkillNotCDActors = new List<FActor>();
                foreach (var a in minStoneNumActors)
                {
                    if(a.GetFSkill(2) != null && a.GetFSkill(2).cooldownCur == 0)
                    {
                        USkillNotCDActors.Add(a);
                    }
                }
                if(USkillNotCDActors.Count == 0)
                {//所有人的大招都处在CD状态，则取全部最少炎魔石的人
                    USkillNotCDActors.AddRange(minStoneNumActors);
                }
                FActor stoneActor = null;
                foreach (var a in USkillNotCDActors)
                {
                    if (stoneActor == null)
                    {
                        stoneActor = a;
                        continue;
                    }
                    if(a.MainPosition.ToFPID() < stoneActor.MainPosition.ToFPID())
                    {//取顺序在最前的人
                        stoneActor = a;
                    }
                }
                if(stoneActor != null)
                {
                    stoneActor.attribute.magicStoneNum += 1;
                    //加特殊buff
                    string stoneBuff = data.tableDataUtil.GetMagicStoneBuff();
                    Buff buff = FBuffFactory.CreateBuff(stoneBuff, data).Clone();
                    buff.LoadBuff(stoneActor, this.cast, TalentBuffTriggerTimer.AllAtt, exportOnceData);

                    Debug.LogFightMsg("--------ProcMagicStone:stoneActor from " + target.heroId + " to " + stoneActor.heroId);

                    FExportValue exportValue = new FExportValue();
                    exportValue.Init(target, stoneActor, ExportValueClass.MAGIC_STONE, 1);
                    exportOnceData.values.Add(exportValue);
                }
            }
        }

    }

}
